package JUC.CountDownLatch和cyclicBarrier和Semaphore的使用;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @author CKC
 * @DateTime 2021/3/31 19:07
 *
 * 使用场景：CountDownLatch一般是用于某个线程等待其他线程执行完之后，它才能执行；
 */
public class CountDownLatchDemo {

    public static void main(String[] args) throws Exception {
        closeDoor();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        closeDoorOk();
    }

    private static void closeDoorOk() throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t 国，被灭");
                countDownLatch.countDown();
            }, CountEnum.forEach_CountTryEnum(i).getRetMessage()).start();
        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + "\t ***********秦帝国，一统华夏");

        /**枚举的特殊用法*/

        System.out.println(CountEnum.ONE);
        System.out.println(CountEnum.ONE.getRetCode());
        System.out.println(CountEnum.ONE.getRetMessage());
    }

    private static void closeDoor() throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t 上完晚自习，离开教室");

                countDownLatch.countDown();
                /**
                 * *    countDownLatch.countDown();
                 * 减少锁存器的计数，如果计数达到零，则释放所有等待线程。
                 * 如果当前计数大于零，则将其递减。 如果新计数为零，则将重新启用所有等待线程以进行线程调度。
                 * 如果当前计数等于零，那么什么也不会发生
                 */
                System.out.println("释放了");
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();
        /**
         *         countDownLatch.await();
         * 导致当前线程等待，直到锁存器递减计数到零为止，除非该线程被中断。
         * 如果当前计数为零，则此方法立即返回。
         * 如果当前计数大于零，则出于线程调度目的，当前线程将被禁用，并且在发生以下两种情况之一之前，它处于休眠状态：
         * 由于countDown方法的调用，计数达到零。 或者
         * 其他一些线程中断当前线程。
         * 如果当前线程：
         * 在进入此方法时已设置其中断状态； 或者在等待期间被打断，
         * *然后抛出InterruptedException并清除当前线程的中断状态。
         */
//        for (int i = 1; i <= 6; i++) {
//            new Thread(() -> {
//                System.out.println(Thread.currentThread().getName() + "\t 上完晚自习，离开教室");
//
//                countDownLatch.countDown();
//                /**
//                 * *    countDownLatch.countDown();
//                 * 减少锁存器的计数，如果计数达到零，则释放所有等待线程。
//                 * 如果当前计数大于零，则将其递减。 如果新计数为零，则将重新启用所有等待线程以进行线程调度。
//                 * 如果当前计数等于零，那么什么也不会发生
//                 */
//                System.out.println("释放了");
//            }, String.valueOf(i)).start();
//        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + "\t ***********班长最后一个走，关门；");
    }
}
